home *** CD-ROM | disk | FTP | other *** search
- //: C25:BeeAndFlowers.cpp
- // From Thinking in C++, 2nd Edition
- // Available at http://www.BruceEckel.com
- // (c) Bruce Eckel 1999
- // Copyright notice in Copyright.txt
- // Demonstration of "visitor" pattern
- #include "../purge.h"
- #include <iostream>
- #include <string>
- #include <vector>
- #include <algorithm>
- #include <cstdlib>
- #include <ctime>
- using namespace std;
-
- class Gladiolus;
- class Renuculus;
- class Chrysanthemum;
-
- class Visitor {
- public:
- virtual void visit(Gladiolus* f) = 0;
- virtual void visit(Renuculus* f) = 0;
- virtual void visit(Chrysanthemum* f) = 0;
- virtual ~Visitor() {}
- };
-
- class Flower {
- public:
- virtual void accept(Visitor&) = 0;
- virtual ~Flower() {}
- };
-
- class Gladiolus : public Flower {
- public:
- virtual void accept(Visitor& v) {
- v.visit(this);
- }
- };
-
- class Renuculus : public Flower {
- public:
- virtual void accept(Visitor& v) {
- v.visit(this);
- }
- };
-
- class Chrysanthemum : public Flower {
- public:
- virtual void accept(Visitor& v) {
- v.visit(this);
- }
- };
-
- // Add the ability to produce a string:
- class StringVal : public Visitor {
- string s;
- public:
- operator const string&() { return s; }
- virtual void visit(Gladiolus*) {
- s = "Gladiolus";
- }
- virtual void visit(Renuculus*) {
- s = "Renuculus";
- }
- virtual void visit(Chrysanthemum*) {
- s = "Chrysanthemum";
- }
- };
-
- // Add the ability to do "Bee" activities:
- class Bee : public Visitor {
- public:
- virtual void visit(Gladiolus*) {
- cout << "Bee and Gladiolus\n";
- }
- virtual void visit(Renuculus*) {
- cout << "Bee and Renuculus\n";
- }
- virtual void visit(Chrysanthemum*) {
- cout << "Bee and Chrysanthemum\n";
- }
- };
-
- struct FlowerGen {
- FlowerGen() { srand(time(0)); }
- Flower* operator()() {
- switch(rand() % 3) {
- default:
- case 0: return new Gladiolus();
- case 1: return new Renuculus();
- case 2: return new Chrysanthemum();
- }
- }
- };
-
- int main() {
- vector<Flower*> v(10);
- generate(v.begin(), v.end(), FlowerGen());
- vector<Flower*>::iterator it;
- // It's almost as if I added a virtual function
- // to produce a Flower string representation:
- StringVal sval;
- for(it = v.begin(); it != v.end(); it++) {
- (*it)->accept(sval);
- cout << string(sval) << endl;
- }
- // Perform "Bee" operation on all Flowers:
- Bee bee;
- for(it = v.begin(); it != v.end(); it++)
- (*it)->accept(bee);
- purge(v);
- } ///:~
-